/**
 * 
 */
package controllers;

import java.util.List;

import client.MainController;
import client.gui.MainPanel;
import client.gui.panels.ChangeCommitteeMembers;
import client.gui.panels.ChangeInspector;
import client.gui.panels.PanelIF;
import client.gui.panels.ReportSearch;
import client.gui.panels.TicketsTablePanel;
import client.gui.panels.TrackTicket;
import client.gui.panels.ViewTicket;
import entities.Message;
import entities.MsgType;
import entities.TableType;
import entities.Ticket;
import entities.User;

/**
 * @author Vodi
 * MainPanelController - a major controller for the main panel.
 */
public class MainPanelController implements ControllerIF {

	/**
	 * the controlled panel
	 */
	private MainPanel mainPanel;
	
	/**
	 * the main controller
	 */
	private MainController mainController;
	
	/**
	 * reference for the inner panel's controller
	 */
	private ControllerIF innerPanelController;
	

	
	public MainPanelController(MainController mainController) {
		this.mainController = mainController;
	}
	
	/**
	 * Get the connected user details
	 * @return
	 */
	public User getUser() {
		return mainController.getUser();
	}
	
	/**
	 * Get the user's first name
	 * @return String
	 */
	public String getUserFirstName() {
		return mainController.getUser().getFirstName();
	}
	
	/* (non-Javadoc)
	 * @see controllers.ControllerIF#action()
	 */
	@Override
	public void action() {
		switch (mainPanel.getTreeSelection()) {
		/*******************************
		 ****   Open to all users   ****
		 *******************************/
		case "Start new request":
			innerPanelController = new NewRequestController(this);
			mainController.informationSystemRequest();
			break;
		case "Track ticket":
			innerPanelController = new TrackTicketController(this);
			TrackTicket trackTicket = new TrackTicket();
			innerPanelController.setPanel(trackTicket);
			mainPanel.setInnerPanel(trackTicket);
			break;
		/*******************************
		 *******   View folder   *******
		 *******************************/
		case "List tickets as the ticket initiator":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "NULL", "initiator");
			break;
		/*****************************************
		 **   Information Engineer permission   **
		 *****************************************/
		case "List tickets as inspector":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "NULL", "inspector");
			break;
		case "List tickets as evaluator":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"EVALUATION\"", "evaluator");
			break;
		case "List tickets as execution leader":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"EXECUTION\"", "leader");
			//************************
			break;
		/**********************************************
		 **   Committee member/chairman permission   **
		 **********************************************/
		case "List tickets as committe member":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"REVIEW\"", "committee");
			break;
		case "List tickets as tester":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"VERIFICATION\"", "tester");
			break;
		/*******************************
		 *****   Requests Folder   *****
		 *******************************/
		case "Time extension request":
			//TableType.TIME_EXTENSION
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TIME_EXTENSION));
			mainController.ticketsListRequest(MsgType.LIST_TIME_EXTENSTIONS_REQUESTS_REQUEST, "NULL", "NULL");
			break;
		case "Review time extensions requests":
			break;
		case "View suspended tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STATUS_REQUEST, "\"SUSPENDED\"", "inspector");
			break;
		case "View running tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STATUS_REQUEST, "\"RUNNING\"", "inspector");
			break;
		/*********************************
		 **   Manager permission ONLY   **
		 *********************************/
		case "Assigning inspector to tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"NEW\"", "NULL");
			break;
		case "Replace inspector in ticket":
			menuContentLoader(null, new ChangeInspector());
//			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"NEW\"", "NULL");
			break;
		case "Replace committee members":
			menuContentLoader(null, new ChangeCommitteeMembers());
//			mainController.ticketsListRequest(MsgType.REPLACE_COMMITTEE_MEMBER_REQUEST, "NULL", "NULL");
			break;
		/********************************
		 *******   Views folder   *******
		*********************************/
		case "List all users":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.USERS_LIST));
			mainController.ticketsListRequest(MsgType.LIST_ALL_USERS_REQUEST, "NULL", "NULL");
			break;
		case "View all tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_ALL_REQUEST, "NULL", "NULL");
			break;
		case "View all running tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STATUS_REQUEST, "\"RUNNING\"", "NULL");
			break;
		case "View all suspended tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STATUS_REQUEST, "\"SUSPENDED\"", "NULL");
			break;
		case "View all closed tickets":
			menuContentLoader(new TicketsTableController(this), new TicketsTablePanel(TableType.TICKETS_LIST));
			mainController.ticketsListRequest(MsgType.TICKET_LIST_STAGE_REQUEST, "\"COMPLETED\"", "NULL");
			break;
		case "View reports":
			menuContentLoader(new ReportsController(), new ReportSearch());
			break;
		default:
			break;
		}
	}
		
	/**
	 * Set a content panel to display inside the main panel 
	 * @param innerPanel PanelIF
	 */
	public void setInnerPanel(PanelIF innerPanel) {
		mainPanel.setInnerPanel(innerPanel);
	}
	
	/**
	 * set the guest panel controller reference
	 * @param innerPanelController ControllerIF
	 */
	public void setInnerPanelController(ControllerIF innerPanelController) {
		this.innerPanelController = innerPanelController;
	}
	
	@Override
	public PanelIF getPanel() {
		return mainPanel;
	}
	
	@Override
	public void setPanel(PanelIF panel) {
		this.mainPanel = (MainPanel) panel;
	}
	
	/**
	 * Sets the main panel that correspond with the controller
	 * @param mainPanel PanelIF
	 */
	public void setMainPanel(PanelIF mainPanel) {
		this.mainPanel = (MainPanel) mainPanel;
	}

	/**
	 * Small method to set the inner panel according to JTree selected option
	 * @param controller
	 * @param panel
	 */
	public void menuContentLoader(ControllerIF controller, PanelIF panel) {
		innerPanelController = controller;
		panel.setController(innerPanelController);
		innerPanelController.setPanel(panel);
		mainPanel.setInnerPanel(panel);
	}
	
	/**
	 * Receiving a message from server and delivers it to the inner panel 
	 */
	@Override
	public void decipherMessage(Message message) {
		if(message.getMsgType().equals(MsgType.TICKET_DETAILS_RESPONSE)) {
			ViewTicketController viewTicketController = new ViewTicketController(this);
			PanelIF viewTicketPanel = new ViewTicket((Ticket) message.getObject(), viewTicketController);
			menuContentLoader(viewTicketController, viewTicketPanel);
		}
		else {
			innerPanelController.decipherMessage(message);
		}
	}

	/**
	 * Sends string to frame to show as regular message
	 * @param string
	 */
	public void showSplashMessage(String string) {
		mainController.showSplashMessage(string);
	}
	
	/**
	 * Sends string to frame to show as error
	 * @param string
	 */
	public void showErrorMessage(String string) {
		mainController.showErrorMessage(string);
	}


	/**
	 * Sends a ticket to server for storage
	 * @param ticket Ticket
	 */
	public void storeTicket(Ticket ticket) {
		mainController.storeTicket(ticket);
	}
	
	/**
	 * Send a request to server to get the details of a specific ticket
	 * @param ticketId
	 */
	public void ticketDetailsRequest(Long ticketId) {
		mainController.ticketDetailsByIdRequest(ticketId);
	}
	
	/**
	 * Sends a request to server to get a list of tickets
	 * @param msgType
	 * @param statusName represents ticket's status - new, assigning etc...
	 * @param userIndicator	states user's role - such as inspector, evaluator etc...
	 */
	public void ticketsListRequest(MsgType msgType, String statusName, String userIndicator) {
		mainController.ticketsListRequest(msgType, statusName, userIndicator);
	}


	/**
	 * Sends a request to server to get a tracking about ticket's progress
	 * @param ticketId Long
	 */
	public void ticketTrackingRequest(Long ticketId) {
		mainController.ticketTrackingRequest(ticketId);
	}

	/**
	 * Sends a given message to server
	 * @param message Message
	 */
	public void sendMessage(Message message) {
		mainController.sendMessage(message);
	}

	/**
	 * Get the committee chairman
	 * @return User
	 */
	public User getCommitteeChairmam() {
		return mainController.getCommitteeChairman();
	}

	/**
	 * Get a list of the committee members (chairman not included)
	 * @return List<User>
	 */
	public List<User> getCommitteeMembers() {
		return mainController.getCommitteeMembers();
	}
	
}
